import { IStore } from "@shared/types";
import { action, observable } from "mobx";
import { useStore } from ".";

export class AsyncStore<T extends IStore> {
    @observable
    loading = false;

    store: T;

    constructor(store?: T) {
        if (!store) {
            store = useStore<T>();
        }
        this.store = store;
    }

    async doSubmit(...rest) {

    }

    async failBack() {
        
    }

    @action
    async submit(...rest) {
        this.loading = true;
        try {
            await this.doSubmit.apply(this, rest);
            this.loading = false;
        } catch (err) {
            this.loading = false;
            await this.failBack();
            throw err;
        }
    }
}

class SubStores<T extends IStore> {
    stores: Record<string, AsyncStore<T>> = {};

    init(stores: Record<string, AsyncStore<T>> | AsyncStore<T>) {
        if (stores.hasOwnProperty('submit') && stores.hasOwnProperty('failBack')) {
            this.stores['*'] = stores as AsyncStore<T>;
        } else {
            for (const key in stores) {
                this.stores[key] = stores[key];
            }
        }
    }
};

export class PageStore<T extends IStore> extends AsyncStore<T> {

    subStores: SubStores<T> = new SubStores<T>();

    constructor(store?: T) {
        super(store);
        this.subStores.init(this.initSubStores());
    }

    protected initSubStores(): Record<string, AsyncStore<T>> | AsyncStore<T> {
        return this;
    }
    
    use(name: string): AsyncStore<T> {
        return this.subStores.stores[name];
    }
    
}